package api

import (
	"config-client-v1/init/global"
	"config-client-v1/model"
	"config-client-v1/utils/tools"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/xuri/excelize/v2"
	"gorm.io/gorm"
	"path/filepath"
)

type ProjectController struct {
}

func (con ProjectController) LoginInfo(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	user := model.User{}
	err := model.DB.Where("id = ?", userToken.Uid).First(&user).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"user_info":  user,
			"token_data": userToken,
		},
	})

}

func (con ProjectController) ProjectDetail(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	info := model.Project{}
	err := model.DB.Model(&model.Project{}).
		Preload("PPEList", func(tx *gorm.DB) *gorm.DB {
			return tx.Preload("FrameList", func(tx2 *gorm.DB) *gorm.DB {
				return tx2.Preload("FrameItem")
			})
		}).
		Preload("FSEList", func(tx *gorm.DB) *gorm.DB {
			return tx.Preload("FSModule", func(tx2 *gorm.DB) *gorm.DB {
				return tx2.Preload("FrameItem")
			})
		}).
		Where("id = ?", userToken.ProjectID).First(&info).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"info": info,
		},
	})
}

func (con ProjectController) PageGroupDetail(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	info := model.PageGroup{}
	err := model.DB.Preload("PageList", func(db *gorm.DB) *gorm.DB {
		return db.Where("del = 0").Order("id DESC")
	}).Model(&model.PageGroup{}).Where("id = ?", userToken.ProjectID).First(&info).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"info": info,
		},
	})
}

func (con ProjectController) LogList(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		Type int `json:"type"`
		model.QueryData
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}

	tx := model.DB.Where("project_id = ?", userToken.ProjectID)
	if param.StartTime != "" {
		tx.Where("create_time >= ?", param.StartTime)
	}
	if param.EndTime != "" {
		tx.Where("create_time <= ?", param.EndTime)
	}
	if param.Type != 0 {
		tx.Where("`type` = ?", param.Type)
	}
	if param.Search != "" {
		tx.Where("`desc` like ?", "%"+param.Search+"%")
	}

	var count int64
	list := make([]model.OperationLog, 0)
	err = tx.Model(&model.OperationLog{}).Count(&count).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	err = tx.Preload("UserInfo").Order("id desc").Offset(param.StartPage()).Limit(param.PageSize).Find(&list).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"list":  list,
			"count": count,
		},
	})

}

func (con ProjectController) LogExport(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		model.QueryData
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}

	tx := model.DB.Where("project_id = ?", userToken.ProjectID)
	if param.StartTime != "" {
		tx.Where("create_time >= ?", param.StartTime)
	}
	if param.EndTime != "" {
		tx.Where("create_time <= ?", param.EndTime)
	}
	if param.Search != "" {
		tx.Where("`desc` like ?", "%"+param.Search+"%")
	}

	list := make([]model.OperationLog, 0)
	err = tx.Preload("UserInfo").Order("id desc").Offset(param.StartPage()).Limit(param.PageSize).Find(&list).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	f := excelize.NewFile()
	sheetName := "Sheet1"
	index, _ := f.NewSheet(sheetName)
	f.SetActiveSheet(index)
	style, _ := f.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{
			Horizontal: "center", // 水平居中
			Vertical:   "center", // 垂直居中
		},
		Border: []excelize.Border{
			{Type: "left", Color: "999999", Style: 1},   // 左边框：蓝色，粗线
			{Type: "right", Color: "999999", Style: 1},  // 右边框：蓝色，粗线
			{Type: "top", Color: "999999", Style: 1},    // 上边框：蓝色，粗线
			{Type: "bottom", Color: "999999", Style: 1}, // 下边框：蓝色，粗线
		},
	})
	err = f.SetCellStyle(sheetName, "A1", "C1", style)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    1,
			"message": err.Error(),
			"data":    "设置excel样式失败",
		})
		return
	}
	// 设置列宽
	_ = f.SetColWidth(sheetName, fmt.Sprintf("%c", 'A'), fmt.Sprintf("%c", 'A'), 100.0)
	_ = f.SetColWidth(sheetName, fmt.Sprintf("%c", 'C'), fmt.Sprintf("%c", 'C'), 20.0)
	// 顶部标题合并行, 并设置行高, 填值
	_ = f.SetRowHeight(sheetName, 1, 25.0)
	_ = f.SetCellValue(sheetName, fmt.Sprintf("A1"), "操作内容")
	_ = f.SetCellValue(sheetName, fmt.Sprintf("B1"), "操作人")
	_ = f.SetCellValue(sheetName, fmt.Sprintf("C1"), "操作时间")

	i := 2
	for _, row := range list {
		_ = f.SetCellValue(sheetName, fmt.Sprintf("A%d", i), row.Desc)
		_ = f.SetCellValue(sheetName, fmt.Sprintf("B%d", i), row.UserInfo.Username)
		_ = f.SetCellValue(sheetName, fmt.Sprintf("C%d", i), row.CreateTime)
		i++
	}
	outputName := "tmp/" + tools.GetTimestamp() + "-operation-log.xlsx"
	outputFile := filepath.Join(global.StaticPath, outputName)
	tools.CreateDir(filepath.Dir(outputFile))
	if err = f.SaveAs(outputFile); err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "保存excel文件失败",
			"data":    map[string]interface{}{},
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"url": outputName,
		},
	})
}

func (con ProjectController) LogSave(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		Type int    `json:"type" binding:"required"`
		Desc string `json:"desc" binding:"required,max=512"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	data := model.OperationLog{
		ProjectID:  userToken.ProjectID,
		UID:        userToken.Uid,
		Type:       param.Type,
		Desc:       param.Desc,
		CreateTime: tools.GetNow(),
	}
	err = model.DB.Omit("UserInfo").Create(&data).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})
}

func (con ProjectController) UpdatePageExpData(ctx *gin.Context) {
	param := struct {
		PageID  int    `json:"page_id" binding:"required"`
		ExpData string `json:"exp_data"`
		Content string `json:"content"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数" + err.Error(),
			"data":    map[string]interface{}{},
		})
		return
	}
	old := &model.Page{}
	pageExist, err2 := old.Exists(param.PageID)
	if !pageExist {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的id",
			"data":    err2,
		})
		return
	}
	updateData := make(map[string]interface{})
	updateData["exp_data"] = param.ExpData
	updateData["content"] = param.Content
	err = model.DB.Model(&model.Page{}).Where("id = ?", param.PageID).Updates(&updateData).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	old.ExpData = param.ExpData
	_ = old.ParseExpData()
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})
}

func (con ProjectController) UpdateContentCeshi(ctx *gin.Context) {
	param := struct {
		PageID       int    `json:"page_id" binding:"required"`
		ContentCeshi string `json:"content_ceshi"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数" + err.Error(),
			"data":    map[string]interface{}{},
		})
		return
	}
	old := &model.Page{}
	pageExist, err2 := old.Exists(param.PageID)
	if !pageExist {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的id",
			"data":    err2,
		})
		return
	}
	updateData := make(map[string]interface{})
	updateData["content_ceshi"] = param.ContentCeshi
	err = model.DB.Model(&model.Page{}).Where("id = ?", param.PageID).Updates(&updateData).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})
}
